#!/usr/bin/python
#this should create a directory and fill it with the files
#corresponding to the selected tag
#usage
#tagcd.py tag

#LOGIC OPERATIONS
#
# AND
# OR
# XOR

import os 
import sys
import hashlib


taggerDir = os.path.expanduser('~/.tagger')
workDir='.WORKDIR'
workDirPath = os.path.join(taggerDir,workDir)

dataFile = os.path.expanduser('~/.tagger/dic')
dataBase = {}

def loadDB():
   global dataBase
   if dataBase=={}:
      db = open(dataFile,'r')
      dataBase = eval(db.read())
      db.close()

loadDB()


def myMkdir(fullpath):
   """Only cretes a directory if it doesn't already exists"""
   if not(os.path.exists(fullpath)):
      os.mkdir(fullpath)

def getTags(md5str):
   """Use it to obtain a list with all the tags of a file"""
   tags=[]
   for root, dirs, files in os.walk(taggerDir):
      tag = os.path.basename(root)
      if md5str in files:
	 tags.append(tag)
      if workDir in dirs:
	 dirs.remove(workDir) #dont walk in here

   return set(tags)

def qMd5(fullpath):
   """Quickly return the md5 sum of fullpath"""
   m=hashlib.md5()
   m.update(fullpath)
   return m.hexdigest()

def getMostPopularTag(taglist):
   """ From taglist return the tag with more files """
   if len(taglist)==0:
      return ""
   maximus=0
   for tag in taglist:
      if dataBase[tag]>maximus:
	 maximus=dataBase[tag]
	 retTag=tag

   return retTag

def addFile(link,root):
   """
   This function attempts to add a file to the root directory
      
      if the filename is already in use then it returns the
      fullpath to the previous file

      else it returns ""
   """
   fullpath = os.readlink(link)
   basename = os.path.basename(fullpath)
   destFp = os.path.join(root,basename)
   #print "AddFile", fullpath, basename, destFp
   if os.path.exists(destFp):
      print "Exists ", destFp
      return destFp
   else:
      print "Adding ", destFp
      os.symlink(os.readlink(link),destFp) 
      return ""
   

def relocateFiles(old,new,root):
   """
      def relocateFiles(fileA,optionsA,fileB,optionsB)
      
      file A: the first file
      optionsA: optionals tags where to relocate the file

   """

   print "Relocating"
   print "Old", old
   print "New", new
   oldmd5 = os.path.basename(old)
   newmd5 = os.path.basename(new)
   oldT  = getTags(oldmd5) #the tags of the previous file
   newT = getTags(newmd5)  # the tags of the upcoming file
   print oldT
   print newT

   if (oldT==newT):
      print "I see no difference"
      return 1

   #oldDiff = listsDiff(oldT,newT)
   oldDiff = oldT-newT
   bestOldTag = getMostPopularTag(oldDiff)
   oldRoot = os.path.join(root,bestOldTag)
   print oldDiff
   print bestOldTag
   print oldRoot
   myMkdir(oldRoot)
   addFile(old,oldRoot)


   #newDiff = listsDiff(newT,oldT)
   newDiff = newT - oldT
   bestNewTag = getMostPopularTag(newDiff)
   newRoot = os.path.join(root,bestNewTag)
   print newDiff
   print bestNewTag
   print newRoot
   myMkdir(newRoot)
   addFile(new,newRoot)

   return 0

def getTag(tag):
   """Returns a list of links under tag"""
   #check wheter the tag exists
   prospect = os.path.join(taggerDir,tag)

   if not os.path.exists(prospect):
      print "Tag: "+tag+" is not populated."
      return set()

   return set(os.listdir(prospect))

def populate(root,linksList):
   """ 
      Use this to populate the root directory with the linksList,
      If a collision is found i will be resolved using the mostPopularTag
   """
   print root

   #linksList = getTag(tag)
   prospect = os.path.join(taggerDir,".all")

   #os.chdir(root)

   for link in linksList:
      linkFp = os.path.join(prospect,link)
      prevFp = addFile(linkFp,root)
      if prevFp!="":
	 print "Collision"
	 print "Prev ", os.readlink(prevFp)
	 old=qMd5(os.readlink(prevFp))
	 os.remove(prevFp)
	 oldFp = os.path.join(prospect,old)
	 relocateFiles(oldFp,linkFp,root)
   return 0
   
def interpret(cmdlist):
   """interprets a lists of commands"""
   print cmdlist
   initial = getTag(cmdlist[0])

   i=1
   print initial
   while(i<len(cmdlist)):
      if cmdlist[i]=="AND":
	 result = initial & getTag(cmdlist[i+1])
      elif cmdlist[i]=="OR":
	 result = initial | getTag(cmdlist[i+1])
      elif cmdlist[i]=="XOR":
	 result = (initial | getTag(cmdlist[i+1])) - (initial & getTag(cmdlist[i+1]))
      else:
	 print "ERROR interpreting!"
      i=i+2
      initial=result
      print initial

   return initial

links=interpret(sys.argv[1:len(sys.argv)])
populate(workDirPath,links)
